#ifndef BASE_MACRO_DEF_H
#define BASE_MACRO_DEF_H

#include <errno.h>
#include <stddef.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <cstdlib>

#include <arpa/inet.h>

#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <list>

#include <pthread.h>

#ifndef uint8
#define uint8 uint8_t
#endif

#ifndef uint16
#define uint16 uint16_t
#endif

#ifndef uint32
#define uint32 uint32_t
#endif

#ifndef uint64
#define uint64 uint64_t
#endif

#ifndef int8
#define int8 int8_t
#endif

#ifndef int16
#define int16 int16_t
#endif

#ifndef int32
#define int32 int32_t
#endif

#ifndef int64
#define int64 int64_t
#endif

#include <glog/logging.h>
#include <gflags/gflags.h>

#define DISALLOW_COPY_AND_ASSIGN(Type) \
  Type (const Type&); \
  void operator = (const Type&)

#define set_nonblock(fd) \
  ::fcntl(fd, F_SETFL, ::fcntl(fd, F_GETFL)|O_NONBLOCK)

#define set_block(fd) \
  ::fcntl(fd, F_SETFL, ::fcntl(fd, F_GETFL) & !O_NONBLOCK)

#define set_cloexec(fd) \
  ::fcntl(fd, F_SETFL, ::fcntl(fd, F_GETFL)|O_CLOEXEC)

template<typename Type>
void StlClear(Type* const t) {
  for (typename Type::iterator it = t->begin(); it != t->end(); ++it) {
    delete (*it);
  }

  t->clear();
}

template<typename Type>
void MapClear(Type* const t) {
  for (typename Type::iterator it = t->begin(); it != t->end(); ++it) {
    delete it->second;
  }

  t->clear();
}

template<typename Type>
void StlUnref(Type* const t) {
  for (typename Type::iterator it = t->begin(); it != t->end(); ++it) {
    (*it)->Unref();
  }

  t->clear();
}

template<typename Type>
void MapUnref(Type* const t) {
  for (typename Type::iterator it = t->begin(); it != t->end(); ++it) {
    it->second->Unref();
  }

  t->clear();
}

inline std::string IpToStr(uint32 ip) {
  struct in_addr addr;
  addr.s_addr = ip;
  char buf[128] = { '\0' };
  const char* ret = ::inet_ntop(AF_INET, &addr, buf, sizeof(buf));
  PCHECK(ret != NULL);
  return buf;
}

inline uint32 StrToIp(const std::string& ip) {
  struct in_addr addr;
  int ret = ::inet_pton(AF_INET, ip.c_str(), &addr.s_addr);
  PCHECK(ret != -1);
  return addr.s_addr;
}

#endif  // BASE_MACRO_DEF_H
